/*
 * Logger.java  0.4.0 / Oct 23, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
package com.cute4j.logging;

import com.cute4j.logging.simple.SimpleLogger;

/**
 * Very simple logging API facade.
 * It supports Java 1.4 logging API, Apache Log4J API and implements its own
 * simple logging API.
 *
 * @cute4j.native
 *    generate="header"
 *
 * @author Slobodan Vrkacevic
 * @version 0.4.0
 */
public final class Logger {

// Public Static Fields. -------------------------------------------------------

  /**
   * The <i>information</i> logging level (the value is {@value}).
   */
  public static final int LEVEL_INFO = 0;

  /**
   * The <i>warning</i> logging level (the value is {@value}).
   */
  public static final int LEVEL_WARN = 1;

  /**
   * The <i>error</i> logging level (the value is {@value}).
   */
  public static final int LEVEL_ERROR = 2;

// Private Static Fields. ------------------------------------------------------

  private static LoggingAdapter logAdapter;
  private static boolean enabled;

// Static Initialization. ------------------------------------------------------

  static {
    LoggingAdapter loggingAdapter = null;
    String className = System.getProperty("cute4j.logging.class");
    if (className != null) {
      try {
        Class logAdapterClass = Class.forName(className);
        loggingAdapter = (LoggingAdapter)logAdapterClass.newInstance();
      } catch (Throwable t) {
        loggingAdapter = null;
      }
    }
    if (loggingAdapter == null) {
      loggingAdapter = new SimpleLogger(System.err, System.out);
    }
    logAdapter = loggingAdapter;
    String loggingDisabled = System.getProperty("cute4j.logging.disabled");
    enabled = !"true".equalsIgnoreCase(loggingDisabled);
  }

// Private Constructor. --------------------------------------------------------

 /**
  * Class has no instances.
  */
  private Logger() {
    // empty constructor body
  }

// Public Static Methods. ------------------------------------------------------

  /**
   * Returns current logging API adapter.
   *
   * @return current logging API adapter
   */
  public static LoggingAdapter getLoggingAdapter() {
    return logAdapter;
  }

  /**
   * Sets current logging API adapter.
   *
   * @param loggingAdapter the logging API adapter
   *
   * @throws IllegalArgumentException if the logging adapter is <tt>null</tt>
   */
  public static void setLoggingAdapter(LoggingAdapter loggingAdapter) {
    if (loggingAdapter == null) {
      throw new IllegalArgumentException("Null logging adapter");
    }
    logAdapter = loggingAdapter;
  }

  /**
   * Returns <tt>true</tt> if the logger is enabled.
   *
   * @return <tt>true</tt> if the logger is enabled
   */
  public static boolean isEnabled() {
    return enabled;
  }

  /**
   * Enables/disables the logger.
   *
   * @param enabled if <tt>true</tt> the logger is enabled
   */
  public static void setEnabled(boolean enabled) {
    Logger.enabled = enabled;
  }

  /**
   * Returns <tt>true</tt> if logging on the specified level is enabled.
   *
   * @param level the logging level
   *
   * @return <tt>true</tt> if logging on the specified level is enabled
   */
  public static boolean isLevelEnabled(int level) {
    return (enabled && logAdapter.isLoggable(level));
  }

  /**
   * Logs a message.
   *
   * @param level the logging level
   * @param message the message
   * @param t the throwable
   */
  public static void log(int level, String message, Throwable t) {
    if (enabled) {
      logAdapter.log(level, message, t);
    }
  }

  /**
   * Logs a message.
   *
   * @param level the logging level
   * @param message the message
   */
  public static void log(int level, String message) {
    if (enabled) {
      logAdapter.log(level, message, null);
    }
  }

  /**
   * Logs a message.
   *
   * @param level the logging level
   * @param t the throwable
   */
  public static void log(int level, Throwable t) {
    if (enabled) {
      logAdapter.log(level, null, t);
    }
  }

  /**
   * Logs a message.
   *
   * @param level the logging level
   * @param fileName the file name
   * @param lineNumber the line number
   * @param message the message
   * @param t the throwable
   */
  public static void log(int level, String fileName, int lineNumber,
                         String message, Throwable t) {
    if (enabled) {
      logAdapter.log(level, fileName, lineNumber, message, t);
    }
  }

  /**
   * Logs a message.
   *
   * @param level the logging level
   * @param fileName the file name
   * @param lineNumber the line number
   * @param message the message
   */
  public static void log(int level, String fileName, int lineNumber,
                         String message) {
    if (enabled) {
      logAdapter.log(level, fileName, lineNumber, message, null);
    }
  }

  /**
   * Logs a message.
   *
   * @param level the logging level
   * @param fileName the file name
   * @param lineNumber the line number
   * @param t the throwable
   */
  public static void log(int level, String fileName, int lineNumber,
                         Throwable t) {
    if (enabled) {
      logAdapter.log(level, fileName, lineNumber, null, t);
    }
  }

  /**
   * Returns <tt>true</tt> it error logging is enabled.
   *
   * @return <tt>true</tt> it error logging is enabled
   */
  public static boolean isErrorEnabled() {
    return (enabled && logAdapter.isLoggable(LEVEL_ERROR));
  }

  /**
   * Logs an error message.
   *
   * @param message the error message
   * @param t the throwable to log
   */
  public static void logError(String message, Throwable t) {
    if (enabled) {
      logAdapter.log(LEVEL_ERROR, message, t);
    }
  }

  /**
   * Logs an error message.
   *
   * @param message the error message
   */
  public static void logError(String message) {
    if (enabled) {
      logAdapter.log(LEVEL_ERROR, message, null);
    }
  }

  /**
   * Logs an error throwable.
   *
   * @param t the throwable to log
   */
  public static void logError(Throwable t) {
    if (enabled) {
      logAdapter.log(LEVEL_ERROR, null, t);
    }
  }

  /**
   * Returns <tt>true</tt> it warning logging is enabled.
   *
   * @return <tt>true</tt> it warning logging is enabled
   */
  public static boolean isWarningEnabled() {
    return (enabled && logAdapter.isLoggable(LEVEL_WARN));
  }

  /**
   * Logs a warning message.
   *
   * @param message the warning message
   * @param t the throwable to log
   */
  public static void logWarning(String message, Throwable t) {
    if (enabled) {
      logAdapter.log(LEVEL_WARN, message, t);
    }
  }

  /**
   * Logs a warning message.
   *
   * @param message the warning message
   */
  public static void logWarning(String message) {
    if (enabled) {
      logAdapter.log(LEVEL_WARN, message, null);
    }
  }

  /**
   * Logs a warning throwable.
   *
   * @param t the throwable to log
   */
  public static void logWarning(Throwable t) {
    if (enabled) {
      logAdapter.log(LEVEL_WARN, null, t);
    }
  }

  /**
   * Returns <tt>true</tt> it information logging is enabled.
   *
   * @return <tt>true</tt> it information logging is enabled
   */
  public static boolean isInfoEnabled() {
    return (enabled && logAdapter.isLoggable(LEVEL_INFO));
  }

  /**
   * Logs an information message.
   *
   * @param message the information message
   */
  public static void logInfo(String message) {
    if (enabled) {
      logAdapter.log(LEVEL_INFO, message, null);
    }
  }

}
